package demoMod.invincibleOne.patches;

import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch;
import com.evacipated.cardcrawl.modthespire.lib.SpireReturn;
import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.unique.RemoveAllPowersAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.Soul;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.localization.CardStrings;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import com.megacrit.cardcrawl.relics.NeowsLament;
import com.megacrit.cardcrawl.vfx.cardManip.ShowCardAndObtainEffect;
import dLib.modcompat.ModManager;
import demoMod.invincibleOne.InvincibleOneMod;
import demoMod.invincibleOne.cards.invincible.AbstractInvincibleCard;
import demoMod.invincibleOne.characters.InvincibleOne;
import demoMod.invincibleOne.interfaces.IOnAddToMasterDeck;
import demoMod.invincibleOne.relics.TheInvinciblesLament;
import spireTogether.SpireTogetherMod;
import spireTogether.network.P2P.P2PManager;
import spireTogether.network.P2P.P2PMessageAnalyzer;
import spireTogether.network.objects.items.NetworkCard;
import spireTogether.util.NetworkMessage;

import java.util.HashMap;
import java.util.UUID;
import java.util.stream.Collectors;

// 联机互坑模式
public class PVPPatch {
    public static String REQ_ADD_CARD = "INV:REQ_ADD_CARD";
    // 等待加入卡组的卡牌们
    public static HashMap<UUID, AbstractCard> pvpCardReceived = new HashMap<>();

    @SpirePatch(clz = P2PMessageAnalyzer.class, requiredModId = "spireTogether", method = "AnalyzeMessage")
    public static class AddCardPatch {
        @SpirePrefixPatch
        public static SpireReturn<Void> Prefix(NetworkMessage data) {
            if (data.request.equals(REQ_ADD_CARD)) {
                NetworkCard dc = (NetworkCard)(data.object);
                AbstractCard c = dc.ToStandard();
                // makeStatEquivalentCopy实例化的对象uuid不同
                AbstractCard cc = c.makeStatEquivalentCopy();
                pvpCardReceived.put(cc.uuid, cc);
                AbstractDungeon.topLevelEffectsQueue.add(new ShowCardAndObtainEffect(cc,
                        (float) Settings.WIDTH / 3.0F, (float)Settings.HEIGHT / 2.0F, false));

                return SpireReturn.Return();
            } else if (data.request.equals(REQ_INVINCIBLE_FORM)) {
                if (AbstractDungeon.player.hasRelic(TheInvinciblesLament.ID)) {
                    AbstractDungeon.player.getRelic(TheInvinciblesLament.ID).counter++;
                } else {
                    new TheInvinciblesLament().instantObtain();
                }
            }
            return SpireReturn.Continue();
        }
    }

    @SpirePatch(
            clz = Soul.class,
            requiredModId = ModManager.TogetherInSpireMod.modId,
            method = "obtain"
    )
    public static class PatchCardObtainPVP {
        @SpirePrefixPatch
        public static SpireReturn<Void> Prefix(Soul soul, AbstractCard card) {
            if (AbstractDungeon.player instanceof InvincibleOne && !(card instanceof IOnAddToMasterDeck) &&
                InvincibleOneMod.isOnlinePVP && SpireTogetherMod.isConnected) {
                if (pvpCardReceived.containsKey(card.uuid)) {
                    pvpCardReceived.remove(card.uuid);
                } else {
                    // 联机坑人PVP
                    Object data = NetworkCard.Generate(card);
                    P2PManager.SendData(new NetworkMessage(PVPPatch.REQ_ADD_CARD, data));
                    return SpireReturn.Return();
                }
            }
            return SpireReturn.Continue();
        }
    }

    public static String PVPModeCardDesc(String id) {
        if (AbstractDungeon.player instanceof InvincibleOne &&
                InvincibleOneMod.isOnlinePVP && SpireTogetherMod.isConnected) {
            return CardCrawlGame.languagePack.getCardStrings(id + "_PVP").DESCRIPTION;
        }
        return CardCrawlGame.languagePack.getCardStrings(id).DESCRIPTION;
    }

    public static String REQ_INVINCIBLE_FORM = "INV:REQ_INVINCIBLE_FORM";
    public static boolean TryUseInvincibleForm() {
        if (AbstractDungeon.player instanceof InvincibleOne &&
                InvincibleOneMod.isOnlinePVP && SpireTogetherMod.isConnected) {

            P2PManager.SendData(new NetworkMessage(PVPPatch.REQ_INVINCIBLE_FORM));
            return true;
        }
        return false;
    }
}
